package at.sysarch.main;

import java.awt.Point;
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;

import at.sysarch.domain.Centroid;
import at.sysarch.domain.Centroids;
import at.sysarch.filter.CentroidFilter;
import at.sysarch.filter.MedianFilter;
import at.sysarch.filter.OpeningFilter;
import at.sysarch.filter.ROIFilter;
import at.sysarch.filter.Sink;
import at.sysarch.filter.Sink.Callback;
import at.sysarch.filter.Source;
import at.sysarch.filter.StoreFilter;
import at.sysarch.filter.ThresholdFilter;
import at.sysarch.utils.DateHelper;

public class Main implements Callback {
	
	private Source _source;
	
	public Main() {
		
		/* Centers of the balls:
		 * 8,78
		 * 72,77
		 * 136,80
		 * 202,81
		 * 266,81
		 * 331,82
		 * 396,82
		 * to calculate we use y-50
		 * */
		
		ArrayList<Point> ballsCenter = new ArrayList<Point>();
		ballsCenter.add(new Point(8, 28));
		ballsCenter.add(new Point(72, 27));
		ballsCenter.add(new Point(136, 30));
		ballsCenter.add(new Point(202, 31));
		ballsCenter.add(new Point(266, 31));
		ballsCenter.add(new Point(331, 32));
		ballsCenter.add(new Point(396, 32));
		
		
		_source = new Source();
		
		Sink sink = new Sink();
		ROIFilter roifilter = new ROIFilter();
		ThresholdFilter thresholdFilter = new ThresholdFilter();
		thresholdFilter.setThresholdParams(0, 30, 255, 0, 254, 0);
		
		ThresholdFilter thresholdFilter3 = new ThresholdFilter();
		thresholdFilter3.setThresholdParams(1, 10, 0, 10, 254, 255);
		
		MedianFilter medianFilter = new MedianFilter();
		MedianFilter medianFilter2 = new MedianFilter();
		OpeningFilter openingFilter = new OpeningFilter();
		StoreFilter storeFilter = new StoreFilter();
		CentroidFilter centroidFilter = new CentroidFilter();
		centroidFilter.setTemplatePoints(ballsCenter);
		centroidFilter.setTolerance(5, 5);
		
		_source.setOutput(roifilter);
		
		//input = Pull
		roifilter.setInput(_source);
		//output = Push
		roifilter.setOutput(thresholdFilter);		
		
		thresholdFilter.setInput(roifilter);
		thresholdFilter.setOutput(medianFilter);
		
		medianFilter.setInput(thresholdFilter);
		medianFilter.setOutput(openingFilter);
		
		openingFilter.setInput(medianFilter);
		openingFilter.setOutput(medianFilter2);
		
		medianFilter2.setInput(openingFilter);
		medianFilter2.setOutput(thresholdFilter3);
		
		thresholdFilter3.setInput(medianFilter2);
		thresholdFilter3.setOutput(storeFilter);		
		
		storeFilter.setInput(thresholdFilter3);
		storeFilter.setOutput(centroidFilter);
		
		centroidFilter.setInput(storeFilter);
		centroidFilter.setOutput(sink);
		
		sink.setInput(centroidFilter);
		
		sink.addListener(this);
	}
	
	@Override
	public void updateResult(Centroids result) {
		
		if (result != null) {

			try {
				String fileName = new StringBuilder().append("result").append(DateHelper.format()).append(".txt").toString();
				BufferedWriter writer = new BufferedWriter(new FileWriter(fileName));
				
				for (Centroid c: result.getCentroids()) {
					
					StringBuilder builder = new StringBuilder();
					
					builder.append("Point:\t");
					builder.append("X:\t");
					builder.append(c.getCentroid().getX());
					builder.append("\tY:\t");
					builder.append(c.getCentroid().getY());
					builder.append("\tTemplate:\t");
					builder.append("X:\t");
					builder.append(c.getTemplatePoint().getX());
					builder.append("\tY:\t");
					builder.append(c.getTemplatePoint().getY());
					builder.append("\tIn tolerance:\t");
					builder.append(c.isInTolerance());
					
					writer.write(builder.toString());
					writer.newLine();
				}
				
				writer.flush();
				writer.close();				
				
			} catch (IOException e) {

				e.printStackTrace();
			}
		}
	}
	
	public static void main(String[] args) {
		
		Main main = new Main();
		main._source.run();
	}
}
